use clap::{Parser, Subcommand};

#[derive(Parser, Debug)]
#[command(name="repox")]
#[command(version="0.1.0")]
#[command(author = "wen.gu")]
#[command(about="a good repo management tool", long_about = None)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Initialize a repo client checkout in the current directory")]
pub struct CommandInit {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Update working tree to the latest revision")]
pub struct CommandSync {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Get info on the manifest branch, current branch or unmerged branches")]
pub struct CommandInfo {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "List projects and their associated directories")]
pub struct CommandList {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Show the working tree status")]
pub struct CommandStatus {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Update working tree to the latest known good revision")]
pub struct CommandSmartSync {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Upload changes for code review")]
pub struct CommandUpload {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Rebase local branches on upstream branch")]
pub struct CommandRebase {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Display overview of unmerged project branches")]
pub struct CommandOverview {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Download and checkout a change")]
pub struct CommandDownload {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Prune (delete) already merged topics")]
pub struct CommandPrune {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Stage file(s) for commit")]
pub struct CommandStage {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}

#[derive(Parser, Clone, Debug)]
#[command(about = "Start a new branch for development")]
pub struct CommandStart {
    ///manifest repository location
    #[arg(short, long="manifest-url")]
    pub url:String,

    ///manifest branch or revision
    #[arg(short, long="manifest-branch", default_value="HEAD")]
    pub branch: String    
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////

#[derive(Subcommand, Debug, Clone)]
pub enum Commands{
    Init(CommandInit),
    List(CommandList),   
    Info(CommandInfo),
    Status(CommandStatus),
    Sync(CommandSync),
    Smartsync(CommandSmartSync),    
    Upload(CommandUpload),
    Rebase(CommandRebase),
    Overview(CommandOverview),
    Download(CommandDownload),      
    Prune(CommandPrune),
    Stage(CommandStage), 
    Start(CommandStart),          
}






pub fn command_parse() -> Cli {
    return Cli::parse();
}
